<template>
  <div class="video-player-container">
    <div class="video-wrapper">
      <video 
        ref="video" 
        id="live-video-player"
        class="video-js vjs-default-skin vjs-live vjs-liveui" 
        playsinline
      />
    </div>

    <!-- 直播状态指示器 -->
    <div v-if="isLive" class="live-indicator">
      <span class="live-dot"></span>
      <span>直播中</span>
    </div>

    <!-- 加载/错误状态 -->
    <div v-if="isLoading" class="loading-indicator">
      <div class="spinner"></div>
    </div>
    <div v-if="errorMessage" class="error-message">
      <p>{{ errorMessage }}</p>
      <button @click="retryPlay" class="retry-btn">重试</button>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, onMounted, onBeforeUnmount, computed } from 'vue'
const { $videojs } = getMDInstance()
// 引入官方新一代 HLS 支持库
// import '@videojs/http-streaming'

// Props 定义
const props = defineProps({
  videoSource: {
    type: String,
    required: true
  },
  isLive: { // 是否为直播流
    type: Boolean,
    default: false
  },
  showControls: {// 是否显示控制条
    type: Boolean,
    default: true
  },
  autoplay: { // 自动播放
    type: Boolean,
    default: false
  },
  muted: { // 自动播放需静音（浏览器政策限制）
    type: Boolean,
    default: true
  },
  poster: {// 首屏封面图片
    type: String,
    default: ''
  },
  loop: { // 是否循环播放（直播流默认不循环）
    type: Boolean,
    default: true
  }
})

// 状态管理
const videoElement = ref(null)
const player = ref(null)
const isLoading = ref(false)
const errorMessage = ref('')
const elementCheckInterval = ref(null)

// 计算视频类型（区分直播流/普通视频）
const videoType = computed(() => {
  const source = props.videoSource.toLowerCase()
  if (source.endsWith('.m3u8')) return 'application/x-mpegURL' // HLS 直播流
  if (source.endsWith('.mpd')) return 'application/dash+xml'   // DASH 直播流
  return 'video/mp4' // 普通视频
})

// 重试播放
const retryPlay = () => {
  initializePlayer()
}

// 安全获取视频元素（避免 ref 绑定失败）
const getVideoElement = () => {
  if (videoElement.value) return videoElement.value
  return document.getElementById('live-video-player') || document.querySelector('video.video-js')
}

// 初始化播放器（核心逻辑）
const initializePlayer = async () => {
  errorMessage.value = ''
  isLoading.value = true

  try {
    // 清除旧定时器（避免内存泄漏）
    if (elementCheckInterval.value) clearInterval(elementCheckInterval.value)

    // 轮询等待 DOM 渲染（确保视频元素存在）
    let element = null
    let checkCount = 0
    const maxChecks = 15 // 最多重试15次（3秒）
    const checkDelay = 200

    await new Promise((resolve, reject) => {
      elementCheckInterval.value = setInterval(() => {
        checkCount++
        element = getVideoElement()

        if (element) {
          clearInterval(elementCheckInterval.value)
          resolve(element)
        } else if (checkCount >= maxChecks) {
          clearInterval(elementCheckInterval.value)
          reject(new Error('视频元素未找到（DOM 渲染超时）'))
        }
      }, checkDelay)
    })

    // 强制设置视频元素基础样式（确保从父级继承尺寸）
    element.style.display = 'block'
    element.style.width = '100%'
    element.style.height = '100%'

    // 销毁旧播放器（避免多实例冲突）
    if (player.value) player.value.dispose()

    // 直播流专属配置（区分普通视频）
    const liveConfig = props.isLive ? {
      liveui: true,          // 启用直播 UI（如“直播中”标识）
      liveTracker: true,     // 跟踪直播进度
      playbackRates: [1],    // 直播禁用倍速播放
      controlBar: {
        progressControl: false, // 直播隐藏进度条（无固定时长）
        liveDisplay: true,      // 显示直播状态控件
        pictureInPictureToggle: false // 直播禁用画中画
      }
    } : {}

    // 初始化 video.js 播放器
    player.value = $videojs(element, {
      autoplay: props.autoplay,
      controls: props.showControls,
      preload: props.isLive ? 'none' : 'auto', // 直播不预加载
      muted: props.muted,
      poster: props.poster,
      playsinline: true, // 移动端内联播放（避免全屏跳转）
      responsive: true,
      fluid: true,       // 自适应容器宽高
      fill: true,        // 填充容器
      loop: props.loop && !props.isLive, // 循环播放（直播流不适用）
      // HLS 直播优化配置（@videojs/http-streaming 专属）
      html5: {
        vhs: {
          overrideNative: true, // 优先使用 JS 解码（避免原生兼容性问题）
          liveWindow: 60,       // 直播可回看窗口（秒）
          maxBufferLength: props.isLive ? 10 : 30, // 直播减少缓冲（降低延迟）
          lowLatencyMode: props.isLive // 直播启用低延迟模式
        }
      },
      sources: [{ type: videoType.value, src: props.videoSource }],
      ...liveConfig
    })

    // 直播流专属事件（断线重连）
    if (props.isLive) {
      // 定期检查直播连接（30秒一次）
      const liveReconnectInterval = setInterval(() => {
        if (player.value && player.value.paused() && !errorMessage.value) {
          console.log('直播断线，尝试重连...')
          player.value.play().catch(err => {
            errorMessage.value = '直播重连失败，请刷新页面'
            console.error('直播重连错误:', err)
          })
        }
      }, 30000)

      // 组件卸载时清除定时器
      onBeforeUnmount(() => clearInterval(liveReconnectInterval))
    }

    // 通用事件监听
    player.value.on('ready', () => {
      console.log('播放器就绪（支持HLS:', !!player.value.tech_.hls, '）')
    })
    player.value.on('error', () => {
      const err = player.value.error()
      const errMsgMap = {
        2: '视频源加载失败',
        3: '视频格式不支持（请确认是.m3u8/.mp4）',
        4: '加载超时（网络不稳定）',
        5: '播放被中断'
      }
      errorMessage.value = errMsgMap[err.code] || `未知错误: ${err.message}`
      isLoading.value = false
    })
    player.value.on('play', () => isLoading.value = false)
    player.value.on('waiting', () => isLoading.value = true)
    player.value.on('canplay', () => isLoading.value = false)

  } catch (err) {
    console.error('播放器初始化错误:', err)
    errorMessage.value = `初始化失败: ${err.message}`
    isLoading.value = false
  }
}

// 播放控制方法（暴露给父组件）
const play = () => player.value?.paused() && player.value.play()
const pause = () => !props.isLive && player.value?.play() && player.value.pause()
const togglePlay = () => props.isLive ? play() : (player.value?.paused() ? play() : pause())
// 添加循环控制方法
const toggleLoop = (loopState) => {
  if (player.value && !props.isLive) {
    player.value.loop(loopState !== undefined ? loopState : !player.value.loop())
    return player.value.loop()
  }
  return false
}
defineExpose({ play, pause, togglePlay, toggleLoop })

// 生命周期钩子
onMounted(() => {
  // 等待 DOM 完全渲染
  Promise.resolve().then(initializePlayer)
})
onBeforeUnmount(() => {
  if (elementCheckInterval.value) clearInterval(elementCheckInterval.value)
  if (player.value) {
    player.value.off() // 移除所有事件监听
    player.value.dispose() // 销毁播放器实例
  }
})

// 监听 Props 变化（如切换视频源）
watch(() => props.videoSource, (newSrc) => {
  if (player.value && newSrc) {
    isLoading.value = true
    player.value.src({ type: videoType.value, src: newSrc })
    player.value.load()
    props.autoplay && player.value.play()
  }
})
watch(() => [props.showControls, props.muted, props.loop], ([controls, muted, loop]) => {
  if (player.value) {
    player.value.controls(controls)
    player.value.muted(muted)
    // 直播流不应用循环设置
    if (!props.isLive) {
      player.value.loop(loop)
    }
  }
})
</script>

<style scoped>
.video-player-container {
  width: 100%;
  height: 100%;
  position: relative;
}

/* 视频容器：从父级继承宽度和高度 */
.video-wrapper {
  width: 100%;
  height: 100%;
  position: relative;
  background-color: #000; /* 直播背景设为黑色 */
}

/* 直播指示器样式 */
.live-indicator {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  background-color: rgba(239, 68, 68, 0.9);
  color: #fff;
  font-size: 12px;
  border-radius: 12px;
  font-weight: 500;
}
.live-dot {
  width: 8px;
  height: 8px;
  background-color: #fff;
  border-radius: 50%;
  animation: pulse 1.2s infinite;
}

/* 覆盖 video.js 默认样式（确保填充容器） */
:deep(#live-video-player) {
  position: absolute !important;
  top: 0 !important;
  left: 0 !important;
  width: 100% !important;
  height: 100% !important;
  object-fit: contain !important; /* 保持视频比例，不拉伸 */
}
:deep(.video-js) {
  position: absolute !important;
  top: 0 !important;
  left: 0 !important;
  width: 100% !important;
  height: 100% !important;
}
:deep(.vjs-tech) {
  position: absolute !important;
  top: 0 !important;
  left: 0 !important;
  width: 100% !important;
  height: 100% !important;
}

/* 加载/错误样式 */
.loading-indicator {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 10;
}
.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid rgba(255, 255, 255, 0.3);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}
.error-message {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.7);
  color: #fff;
  padding: 20px;
  text-align: center;
  z-index: 10;
}
.retry-btn {
  margin-top: 16px;
  padding: 8px 20px;
  background-color: #2563eb;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s;
}
.retry-btn:hover {
  background-color: #1d4ed8;
}

/* 动画定义 */
@keyframes pulse {
  0% { opacity: 1; }
  50% { opacity: 0.5; }
  100% { opacity: 1; }
}
@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
</style>
